/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import com.anwen.mongo.toolkit.StringUtils;
import com.comac.ins.common.redis.utils.RedisUtils;
import com.comac.ins.isfd.constant.RedisConstants;
import com.comac.ins.isfd.domain.*;
import com.comac.ins.isfd.domain.bo.IsfdStatisticalAnalysisBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.mapper.*;
import com.comac.ins.isfd.service.IIsfdDatabaseMongoService;
import com.comac.ins.isfd.service.IsfdNextPlatformService;
import com.comac.ins.isfd.service.IsfdStatisticalAnalysisService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore;
import java.util.stream.Collectors;

/**
 *
 * @date: 2025/4/21 15:57
 **/
@RequiredArgsConstructor
@Service
@Slf4j
public class IsfdStatisticalAnalysisServiceImpl implements IsfdStatisticalAnalysisService {
    @Autowired
    private final IsfdStatisticalAnalysisMapper isfdStatisticalAnalysisMapper;
    @Autowired
    private final IsfdDatabaseTypeManagementMapper isfdDatabaseTypeManagementMapper;
    @Autowired
    private IsfdBusinessDatabaseRefMapper IsfdBusinessDatabaseRefMapper;
    @Autowired
    private final IsfdDatabaseModelConfigMapper isfdDatabaseModelConfigMapper;
    @Autowired
    private IsfdBusinessScenariosMapper isfdBusinessScenariosMapper;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private IsfdNextPlatformService isfdNextPlatformService;

    private final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    @Data
    private static class tempDataBase{
        private Long dataBaseId;
        private Long dataCount;
        private Long dataBaseTopId;
        private String dataBaseName;
        private Long parentId;
    }
    @Override
    public IsfdDataAssetStatisticsVo dataAssetStatistics(IsfdStatisticalAnalysisBo statisticalAnalysisBo,String source) {
        // 先获取缓存，如果获取缓存失败再去db查，后期需要加锁
        Object cacheObject = RedisUtils.getCacheObject(RedisConstants.DATAASSETSTATISTICS_HOME_PAGE_KEY);
        if (cacheObject != null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            return (IsfdDataAssetStatisticsVo) cacheObject;
        }
        IsfdDataAssetStatisticsVo isfdDataAssetStatisticsVo = new IsfdDataAssetStatisticsVo();
        // 数据总量
        final Long[] totalCount = {0L};
        // 根据业务场景查询
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
            //查询要素库
            List<IsfdBusinessDatabaseRefVo> isfdDatabaseRefs = isfdStatisticalAnalysisMapper.selectListByScenarioId(statisticalAnalysisBo.getScenarioId(),statisticalAnalysisBo.getSystemId());
            if (isfdDatabaseRefs.size()>0) {
                // 循环isfdDatabaseTypes
                List<tempDataBase> tempDataList = new ArrayList<>();
                for (IsfdBusinessDatabaseRefVo isfdDatabaseRef : isfdDatabaseRefs) {
                    //储存顶层要素库id
                    IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectById(isfdDatabaseRef.getParentModelId());
                    tempDataBase map = new tempDataBase();
                    map.setDataBaseId(isfdDatabaseRef.getDatabaseTypeId());
                    if(Objects.nonNull(modelConfig)){
                        final Long[] modelCount = {0L};
                        // 查询记录表数据量
                        List<IsfdDatabaseDataImportRecord> records = isfdStatisticalAnalysisMapper.getRecordsByDate(modelConfig.getId(),isfdDatabaseRef.getDatabaseTypeId(),null,null);
                        if (records.size() > 0) {
                            try{
                                List<CompletableFuture<Void>> futures = new ArrayList<>();
                                Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                                for (IsfdDatabaseDataImportRecord record : records) {
                                    semaphore.acquire(); // 获取许可，控制并发批次数
                                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                                        try {
                                            //查询记录子表数据
                                            List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(record.getId());
                                            if (subList.size() > 0) {
                                                for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                                    //计算模型的数据量
                                                    modelCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                                }
                                            } else {
                                                //如果没有子表数据，则直接使用记录表数据量
                                                modelCount[0] += record.getDataQuantity();
                                            }
                                        } catch (Exception e) {
                                            log.error("record子记录表查询失败: {}", e.getMessage());
                                        } finally {
                                            semaphore.release(); // 释放资源
                                        }
                                    }, threadPoolTaskExecutor);
                                    futures.add(future);
                                }
                                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                            } catch (Exception e) {
                                log.error("统计失败 ：" + e.getMessage(), e);
                            }
                        }
                        totalCount[0] += modelCount[0];
                        map.setDataCount(modelCount[0]);
                        IsfdDatabaseTypeManagement isfdDatabaseTypes = isfdDatabaseTypeManagementMapper.selectById(isfdDatabaseRef.getDatabaseTypeId());
                        map.setDataBaseTopId(isfdDatabaseTypes.getTopId());
                        map.setParentId(isfdDatabaseTypes.getParentId());
                        map.setDataBaseId(isfdDatabaseTypes.getId());
                        map.setDataBaseName(isfdDatabaseTypes.getDatabaseName());
                    }
                    tempDataList.add(map);
                }
                //循环tempDataList
                Map<Long, List<tempDataBase>> groupedDataBase = tempDataList.stream()
                    .collect(Collectors.groupingBy(tempDataBase::getDataBaseId));
                //遍历groupedDataBase
                List<IsfdDataAssetStatisticsVo.DataAsset> dataAssetList = new ArrayList<>();
                for (Map.Entry<Long, List<tempDataBase>> entry : groupedDataBase.entrySet()) {
                    Long dataBaseId = entry.getKey();
                    List<tempDataBase> tempDataBases = entry.getValue();
                    //循环tempDataBases
                    String dataBaseName = "";
                    Long dataBaseCount = 0L;
                    IsfdDatabaseTypeManagement topDataBase = isfdDatabaseTypeManagementMapper.selectById(dataBaseId);
                    dataBaseName = topDataBase.getDatabaseName();
                    IsfdDataAssetStatisticsVo.DataAsset dataAsset = new IsfdDataAssetStatisticsVo.DataAsset();
                    for (tempDataBase tempDataBase : tempDataBases) {
                        dataBaseCount += tempDataBase.getDataCount();
                    }
                    dataAsset.setName(dataBaseName);
                    dataAsset.setCount(dataBaseCount);
                    dataAssetList.add(dataAsset);
                }
                isfdDataAssetStatisticsVo.setTotalCount(totalCount[0]);
                isfdDataAssetStatisticsVo.setDataAssetList(dataAssetList);
            }

        }else{//查询全部要素库
            List<IsfdDatabaseTypeManagement> isfdDatabaseTypes = isfdDatabaseTypeManagementMapper.selectList(null);
            if (isfdDatabaseTypes.size()>0) {
                //循环isfdDatabaseTypes
                Map<Long, List<IsfdDatabaseTypeManagement>> groupedDataBase = isfdDatabaseTypes.stream()
                    .collect(Collectors.groupingBy(IsfdDatabaseTypeManagement::getId));
                //循环isfdDatabaseTypeSet
                List<IsfdDataAssetStatisticsVo.DataAsset> dataAssetList = new ArrayList<>();
                for (Map.Entry<Long, List<IsfdDatabaseTypeManagement>> entry : groupedDataBase.entrySet()) {
                    Long dataBaseId = entry.getKey();
                    List<IsfdDatabaseTypeManagement> tempDataBases = entry.getValue();
                    String dataBaseName = "";
                    final Long[] dataBaseCount = {0L};
                    IsfdDatabaseTypeManagement isfdDatabaseTypeOne = isfdDatabaseTypeManagementMapper.selectById(dataBaseId);
                    IsfdDataAssetStatisticsVo.DataAsset dataAsset = new IsfdDataAssetStatisticsVo.DataAsset();
                    for (IsfdDatabaseTypeManagement isfdDatabaseType : tempDataBases) {
                        //查询要素库对应的模型列表
                        List<IsfdBusinessDatabaseRefVo> isfdBusinessDataBaseRefList = new ArrayList<>();
                        isfdBusinessDataBaseRefList = isfdStatisticalAnalysisMapper.selectDataBaseRefByDataBaseId(isfdDatabaseType.getId());
                        //循环isfdBusinessDataBaseRefList
                        for (IsfdBusinessDatabaseRefVo isfdDatabaseRef : isfdBusinessDataBaseRefList) {
                            IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectById(isfdDatabaseRef.getParentModelId());
                            //计算模型的数据量
                            if(Objects.nonNull(modelConfig)){
                                // 查询记录表数据量
                                List<IsfdDatabaseDataImportRecord> records = isfdStatisticalAnalysisMapper.getRecordsByDate(modelConfig.getId(),isfdDatabaseRef.getDatabaseTypeId(),null,null);
                                if (records.size() > 0) {
                                    try{
                                        List<CompletableFuture<Void>> futures = new ArrayList<>();
                                        Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                                        for (IsfdDatabaseDataImportRecord record : records) {
                                            semaphore.acquire(); // 获取许可，控制并发批次数
                                            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                                                try {
                                                    //查询记录子表数据
                                                    List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(record.getId());
                                                    if (subList.size() > 0) {
                                                        for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                                            //计算模型的数据量
                                                            dataBaseCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                                            totalCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                                        }
                                                    } else {
                                                        //如果没有子表数据，则直接使用记录表数据量
                                                        dataBaseCount[0] += record.getDataQuantity();
                                                        totalCount[0] += record.getDataQuantity();
                                                    }
                                                } catch (Exception e) {
                                                    log.error("record子记录表查询失败: {}", e.getMessage());
                                                } finally {
                                                    semaphore.release(); // 释放资源
                                                }
                                            }, threadPoolTaskExecutor);
                                            futures.add(future);
                                        }
                                        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                                    } catch (Exception e) {
                                        log.error("统计失败 ：" + e.getMessage(), e);
                                    }
                                }
                            }
                        }
                    }
                    dataAsset.setName(isfdDatabaseTypeOne.getDatabaseName());
                    dataAsset.setCount(dataBaseCount[0]);
                    dataAssetList.add(dataAsset);
                }
                isfdDataAssetStatisticsVo.setDataAssetList(dataAssetList);
                isfdDataAssetStatisticsVo.setTotalCount(totalCount[0]);
            }
        }
        //查询要素库(模型库、材料库、型材库、参数库、算法库)
        List<IsfdDatabaseTypeManagement> isfdDatabases = new ArrayList<>();
        isfdDatabases = isfdStatisticalAnalysisMapper.selectThreedDataBaseList();
        // 循环isfdDatabases
        List<IsfdDataAssetStatisticsVo.DataAsset> staticAssetList = new ArrayList<>();
        List dataBaseNameList = new ArrayList<>();
        for (IsfdDatabaseTypeManagement isfdDatabaseType : isfdDatabases) {
            // 循环isfdDatabaseTypes
            String dataBaseName = "";
            final Long[] dataBaseCount = {0L};
            IsfdDataAssetStatisticsVo.DataAsset dataAsset = new IsfdDataAssetStatisticsVo.DataAsset();
            List<IsfdDatabaseTypeManagement> isfdBusinessDataBaseList = new ArrayList<>();
            isfdBusinessDataBaseList = isfdStatisticalAnalysisMapper.selectListByTopId(isfdDatabaseType.getId());
            //循环isfdBusinessDataBaseRefList
            for (IsfdDatabaseTypeManagement isfdDatabaseRef : isfdBusinessDataBaseList) {
                    // 查询记录表数据量
                    List<IsfdDatabaseDataImportRecord> records = isfdStatisticalAnalysisMapper.getRecords(statisticalAnalysisBo.getScenarioId(),isfdDatabaseRef.getId());
                    if (records.size() > 0) {
                        try{
                            List<CompletableFuture<Void>> futures = new ArrayList<>();
                            Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                            for (IsfdDatabaseDataImportRecord record : records) {
                                semaphore.acquire(); // 获取许可，控制并发批次数
                                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                                    try {
                                        //查询记录子表数据
                                        List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(record.getId());
                                        if (subList.size() > 0) {
                                            for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                                //计算模型的数据量
                                                dataBaseCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                            }
                                        } else {
                                            //如果没有子表数据，则直接使用记录表数据量
                                            dataBaseCount[0] += record.getDataQuantity();
                                        }
                                    } catch (Exception e) {
                                        log.error("record子记录表查询失败: {}", e.getMessage());
                                    } finally {
                                        semaphore.release(); // 释放资源
                                    }
                                }, threadPoolTaskExecutor);
                                futures.add(future);
                            }
                            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                        } catch (Exception e) {
                            log.error("统计失败 ：" + e.getMessage(), e);
                        }
                    }

            }
            dataBaseName = isfdDatabaseType.getDatabaseName();
            dataAsset.setName(dataBaseName);
            dataAsset.setCount(dataBaseCount[0]);
            staticAssetList.add(dataAsset);
            dataBaseNameList.add(dataBaseName);
        }
        // 判断是否包含五大库
        String[] staticNames = {"模型库","材料库","型材库","参数库","算法库"};
        List<String> staticNameList = Arrays.asList(staticNames);
        List<String> missingElements = (List<String>) staticNameList.stream()
            .filter(e -> !dataBaseNameList.contains(e))
            .collect(Collectors.toList());
        if(missingElements.size()>0){
            for (String missingElement : missingElements) {
                IsfdDataAssetStatisticsVo.DataAsset dataAsset = new IsfdDataAssetStatisticsVo.DataAsset();
                dataAsset.setName(missingElement);
                dataAsset.setCount(0L);
                staticAssetList.add(dataAsset);
            }
        }
        isfdDataAssetStatisticsVo.setStaticAssetList(staticAssetList);
        if (cacheObject == null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            // 放入缓存中，永久有效
            RedisUtils.setCacheObject(RedisConstants.DATAASSETSTATISTICS_HOME_PAGE_KEY, isfdDataAssetStatisticsVo);
        }

        return isfdDataAssetStatisticsVo;
    }

    @Override
    public IsfdGrowthTrendVo growthTrend(IsfdStatisticalAnalysisBo statisticalAnalysisBo,String source) {
        // 先获取缓存，如果获取缓存失败再去db查，后期需要加锁
        Object cacheObject = RedisUtils.getCacheObject(RedisConstants.GROWTHTREND_HOME_PAGE_KEY);
        if (cacheObject != null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId()) && StringUtils.isBlank(statisticalAnalysisBo.getStartTime()) ) {
            return (IsfdGrowthTrendVo) cacheObject;
        }
        // 根据业务场景查询
        //查询要素库(模型库、材料库、型材库、参数库、算法库)
        List<IsfdDatabaseTypeManagement> isfdDatabases = new ArrayList<>();
        if(statisticalAnalysisBo.getDefaultSelect().equals("Y")){
            List<IsfdBusinessDatabaseRefVo> allRefList = isfdStatisticalAnalysisMapper.selectListByScenarioId(statisticalAnalysisBo.getScenarioId(),statisticalAnalysisBo.getSystemId());
            //根据database分组
            Map<Long, List<IsfdBusinessDatabaseRefVo>> groupedDataBase = allRefList.stream()
                .collect(Collectors.groupingBy(IsfdBusinessDatabaseRefVo::getDatabaseTypeId));
            //遍历groupedDataBase
            List<Long> isfdDatabaseIds = new ArrayList<>();
            for (Map.Entry<Long, List<IsfdBusinessDatabaseRefVo>> entry : groupedDataBase.entrySet()) {
                Long dataBaseId = entry.getKey();
                isfdDatabaseIds.add(dataBaseId);
            }
            List<IsfdDatabaseTypeManagementVo> allDataBase = isfdDatabaseTypeManagementMapper.selectVoBatchIds(isfdDatabaseIds);
            //根据topid分组
            Map<Long, List<IsfdDatabaseTypeManagementVo>> groupedDataById = allDataBase.stream()
                .collect(Collectors.groupingBy(IsfdDatabaseTypeManagementVo::getId));
            List<Long> topIds = new ArrayList<>();
            //遍历groupedDataByTopId
            for (Map.Entry<Long, List<IsfdDatabaseTypeManagementVo>> entry : groupedDataById.entrySet()) {
                Long dataBaseId = entry.getKey();
                topIds.add(dataBaseId);
            }
            isfdDatabases = isfdDatabaseTypeManagementMapper.selectBatchIds(topIds);
        }else{
            isfdDatabases = isfdStatisticalAnalysisMapper.selectThreedDataBaseList();
        }
        //设置查询时间范围
        List<String> months = getMonthsBetween(statisticalAnalysisBo.getStartTime(), statisticalAnalysisBo.getEndTime());
        //循环isfdDatabases
        List<IsfdGrowthTrendVo.ThrendData> dataList = new ArrayList<>();
        List dataBaseNameList = new ArrayList<>();
        for (IsfdDatabaseTypeManagement isfdDatabaseType : isfdDatabases) {
            //根据topid查询对应的要素库列表
            List<IsfdBusinessDatabaseRefVo> isfdBusinessDataBaseRefList = new ArrayList<>();
//            List<IsfdDatabaseTypeManagement> isfdDatabaseTypes= isfdStatisticalAnalysisMapper.selectListByTopId(isfdDatabaseType.getId());
            IsfdDatabaseTypeManagement isfdDatabaseTypes = isfdDatabaseTypeManagementMapper.selectById(isfdDatabaseType.getTopId());
//            List<Long> ids = isfdDatabaseTypes.stream().map(IsfdDatabaseTypeManagement::getId).collect(Collectors.toList());
            List<Long> ids = new ArrayList<>();
            ids.add(isfdDatabaseTypes.getId());
            if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
                isfdBusinessDataBaseRefList = isfdStatisticalAnalysisMapper.selectDataBaseRefByIds(ids,statisticalAnalysisBo.getScenarioId());
            }else{
                //查询要素库对应的模型列表
                isfdBusinessDataBaseRefList = isfdStatisticalAnalysisMapper.selectDataBaseRefByIds(ids,null);
            }
            //循环isfdBusinessDataBaseRefList
            IsfdGrowthTrendVo.ThrendData threndData = new IsfdGrowthTrendVo.ThrendData();
            List<IsfdGrowthTrendVo.MonthData> monthDataList = new ArrayList<>();
            for (String month : months) {
                IsfdGrowthTrendVo.MonthData monthData = new IsfdGrowthTrendVo.MonthData();
                monthData.setMonth(month);
                monthData.setDataCount(0L);
                final Long[] count = {0L};
                for (IsfdBusinessDatabaseRefVo isfdDatabaseRef : isfdBusinessDataBaseRefList) {
                    IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectById(isfdDatabaseRef.getParentModelId());
                    //循环monthes
                    if(Objects.nonNull(modelConfig)){
                            //查询每个月的数据量
                            // 解析日期
                            // 1. 解析字符串为日期对象
                            LocalDate date = LocalDate.parse(month);

                            // 2. 计算当月第一天（月初）
                            LocalDate firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());

                            // 3. 计算下月第一天（下月初）
                            LocalDate firstDayOfNextMonth = date.with(TemporalAdjusters.firstDayOfNextMonth());
                            // 查询记录表数据量
                            List<IsfdDatabaseDataImportRecord> records = isfdStatisticalAnalysisMapper.getRecordsByDate(modelConfig.getId(),isfdDatabaseRef.getDatabaseTypeId(), firstDayOfMonth.toString(), firstDayOfNextMonth.toString());
                            if (records.size() > 0) {
                                List<CompletableFuture<Void>> futures = new ArrayList<>();
                                try{
                                    Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                                    for (IsfdDatabaseDataImportRecord record : records) {
                                        semaphore.acquire(); // 获取许可，控制并发批次数
                                        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                                            try {
                                                //查询记录子表数据
                                                List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(record.getId());
                                                if (subList.size() > 0) {
                                                    for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                                        //计算模型的数据量
                                                        count[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                                    }
                                                } else {
                                                    //如果没有子表数据，则直接使用记录表数据量
                                                    count[0] += record.getDataQuantity();
                                                }
                                            } catch (Exception e) {
                                                log.error("record子记录表查询失败: {}", e.getMessage());
                                            } finally {
                                                semaphore.release(); // 释放资源
                                            }
                                        }, threadPoolTaskExecutor);
                                        futures.add(future);
                                    }
                                    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                                }catch (Exception e) {
                                    log.error("统计失败 ：" + e.getMessage(), e);
                                }
                            }
                    }
                }
                monthData.setDataCount(count[0]);
                monthDataList.add(monthData);
            }
            threndData.setName(isfdDatabaseType.getDatabaseName());
            threndData.setData(monthDataList);
            dataList.add(threndData);
            dataBaseNameList.add(isfdDatabaseType.getDatabaseName());
        }
        // 判断是否包含五大库
        String[] staticNames = {"模型库","材料库","型材库","参数库","算法库"};
        List<String> staticNameList = Arrays.asList(staticNames);
        List<String> missingElements = (List<String>) staticNameList.stream()
            .filter(e -> !dataBaseNameList.contains(e))
            .collect(Collectors.toList());
        if(missingElements.size()>0){
            for (String missingElement : missingElements) {
                // 添加月份数据
                IsfdGrowthTrendVo.ThrendData threndData = new IsfdGrowthTrendVo.ThrendData();
                List<IsfdGrowthTrendVo.MonthData> monthDataList = new ArrayList<>();
                for (String month : months) {
                    IsfdGrowthTrendVo.MonthData monthData = new IsfdGrowthTrendVo.MonthData();
                    monthData.setMonth(month);
                    monthData.setDataCount(0L);
                    monthDataList.add(monthData);
                }
                threndData.setName(missingElement);
                threndData.setData(monthDataList);
                dataList.add(threndData);
            }
        }
        IsfdGrowthTrendVo isfdGrowthTrendVo = new IsfdGrowthTrendVo();
        isfdGrowthTrendVo.setMonthes(months);
        isfdGrowthTrendVo.setDataList(dataList);
        if (cacheObject == null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId()) && StringUtils.isBlank(statisticalAnalysisBo.getStartTime())) {
            // 放入缓存中，永久有效
            RedisUtils.setCacheObject(RedisConstants.GROWTHTREND_HOME_PAGE_KEY, isfdGrowthTrendVo);
        }
        return isfdGrowthTrendVo;
    }

    @Override
    public IsfdScenarioDataVo countDataByScenario(IsfdStatisticalAnalysisBo statisticalAnalysisBo,String source) {
        // 先获取缓存，如果获取缓存失败再去db查，后期需要加锁
        Object cacheObject = RedisUtils.getCacheObject(RedisConstants.COUNTDATABYSCENARIO_HOME_PAGE_KEY);
        if (cacheObject != null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            return (IsfdScenarioDataVo) cacheObject;
        }
        IsfdScenarioDataVo isfdScenarioDataVo = new IsfdScenarioDataVo();
        List nameList = new ArrayList<>();
        List<IsfdBusinessDatabaseRefVo> isfdBusinessDatabaseRefs = new ArrayList<>();
        // 根据业务场景查询
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
            //查询要素库
            isfdBusinessDatabaseRefs = isfdStatisticalAnalysisMapper.selectListByScenarioId(statisticalAnalysisBo.getScenarioId(),statisticalAnalysisBo.getSystemId());
        }else{
            //查询所有场景的要素库
            isfdBusinessDatabaseRefs = IsfdBusinessDatabaseRefMapper.selectVoList();
        }
        //未选择业务场景
        Map<Long, List<IsfdBusinessDatabaseRefVo>> groupedDataScene = isfdBusinessDatabaseRefs.stream()
            .collect(Collectors.groupingBy(IsfdBusinessDatabaseRefVo::getSceneId));
        // 选择业务场景未选择业务系统
        List<IsfdBusinessDatabaseRefVo> commonModelList = isfdBusinessDatabaseRefs.stream()
            .filter(isfdBusinessDatabaseRef -> isfdBusinessDatabaseRef.getModelType().equals("common_model"))
            .collect(Collectors.toList());
        List<IsfdBusinessDatabaseRefVo> systemModelList = isfdBusinessDatabaseRefs.stream()
            .filter(isfdBusinessDatabaseRef -> !isfdBusinessDatabaseRef.getModelType().equals("common_model"))
            .collect(Collectors.toList());
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
            groupedDataScene = systemModelList.stream()
                .collect(Collectors.groupingBy(IsfdBusinessDatabaseRefVo::getSystemId));
        }
        List<IsfdScenarioDataVo.ScenarioData> scenarioDataList = new ArrayList<>();
        //遍历groupedDataBase
        for (Map.Entry<Long, List<IsfdBusinessDatabaseRefVo>> entry : groupedDataScene.entrySet()) {
            Long sceneId = entry.getKey();
            //查询场景信息
            IsfdBusinessScenariosVo isfdBusinessScenariosVo = isfdBusinessScenariosMapper.selectVoById(sceneId);
            Map scenarioMap = new HashMap<>();
            scenarioMap.put("scenarioId",sceneId);
            scenarioMap.put("scenarioName",isfdBusinessScenariosVo.getName());
            nameList.add(scenarioMap);
            List<IsfdBusinessDatabaseRefVo> tempDataBases = entry.getValue();
            //查询数据库信息
            List<IsfdDatabaseTypeManagement> isfdDatabaseTypes = isfdDatabaseTypeManagementMapper.selectBatchIds(tempDataBases.stream().map(IsfdBusinessDatabaseRefVo::getDatabaseTypeId).collect(Collectors.toList()));
            //归类isfdDatabaseTypes
            Map<Long, List<IsfdDatabaseTypeManagement>> groupedDataByTopId = isfdDatabaseTypes.stream()
                .collect(Collectors.groupingBy(IsfdDatabaseTypeManagement::getId));
            //遍历groupedDataByTopId
            IsfdScenarioDataVo.ScenarioData scenarioData = new IsfdScenarioDataVo.ScenarioData();
            scenarioData.setScenarioName(isfdBusinessScenariosVo.getName());
            List<IsfdScenarioDataVo.DataBaseData> dataBaseDataList = new ArrayList<>();
            for (Map.Entry<Long, List<IsfdDatabaseTypeManagement>> entry1 : groupedDataByTopId.entrySet()) {
                Long dataBaseTopId = entry1.getKey();
                final Long[] dataBaseCount = {0L};
                List<IsfdDatabaseTypeManagement> tempDataBases1 = entry1.getValue();
                //循环tempDataBases
                String dataBaseName = "";
                IsfdDatabaseTypeManagement isfdDatabaseTop = isfdDatabaseTypeManagementMapper.selectById(dataBaseTopId);
                if(Objects.nonNull(isfdDatabaseTop)){
                    dataBaseName = isfdDatabaseTop.getDatabaseName();
                }
                for (IsfdDatabaseTypeManagement isfdDatabaseType : tempDataBases1) {
                    //查询要素库对应的模型列表
                    List<IsfdBusinessDatabaseRefVo> isfdBusinessDataBaseRefList = new ArrayList<>();
                    isfdBusinessDataBaseRefList = isfdStatisticalAnalysisMapper.selectDataBaseRefByDataBaseId(isfdDatabaseType.getId());
                    //选择了业务场景
                    if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
                        List<IsfdBusinessDatabaseRefVo> filterList  = commonModelList.stream()
                            .filter(isfdBusinessDatabaseRef -> isfdBusinessDatabaseRef.getDatabaseTypeId().equals(isfdDatabaseType.getId()))
                            .collect(Collectors.toList());
                        if(filterList.size()>0){
                            // 将filterList加入到isfdBusinessDataBaseRefList
                            isfdBusinessDataBaseRefList.addAll(filterList);
                        }
                    }
                    //循环isfdBusinessDataBaseRefList
                    for (IsfdBusinessDatabaseRefVo isfdDatabaseRef : isfdBusinessDataBaseRefList) {
                        IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectById(isfdDatabaseRef.getParentModelId());
                        //计算模型的数据量
                        if(Objects.nonNull(modelConfig)){
                            List<IsfdDatabaseDataImportRecord> records = isfdStatisticalAnalysisMapper.getRecordsByDate(modelConfig.getId(),isfdDatabaseRef.getDatabaseTypeId(),null,null);
                            if (records.size() > 0) {
                                List<CompletableFuture<Void>> futures = new ArrayList<>();
                                try{
                                    Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                                    for (IsfdDatabaseDataImportRecord record : records) {
                                        semaphore.acquire(); // 获取许可，控制并发批次数
                                        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                                            try {
                                                //查询记录子表数据
                                                List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(record.getId());
                                                if (subList.size() > 0) {
                                                    for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                                        //计算模型的数据量
                                                        dataBaseCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                                    }
                                                } else {
                                                    //如果没有子表数据，则直接使用记录表数据量
                                                    dataBaseCount[0] += record.getDataQuantity();
                                                }
                                            } catch (Exception e) {
                                                log.error("record子记录表查询失败: {}", e.getMessage());
                                            } finally {
                                                semaphore.release(); // 释放资源
                                            }
                                        }, threadPoolTaskExecutor);
                                        futures.add(future);
                                    }
                                    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                                }catch (Exception e) {
                                    log.error("统计失败 ：" + e.getMessage(), e);
                                }
                            }
                        }
                    }
                }
                IsfdScenarioDataVo.DataBaseData dataBaseData = new IsfdScenarioDataVo.DataBaseData();
                dataBaseData.setDataCount(dataBaseCount[0]);
                dataBaseData.setDataBaseName(dataBaseName);
                dataBaseDataList.add(dataBaseData);
            }
            scenarioData.setDataBaseDatas(dataBaseDataList);
            //将场景名称和数据量添加到场景数据列表中
            scenarioDataList.add(scenarioData);
        }
        isfdScenarioDataVo.setScenarioNames(nameList);
        isfdScenarioDataVo.setDataList(scenarioDataList);
        if (cacheObject == null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            // 放入缓存中，永久有效
            RedisUtils.setCacheObject(RedisConstants.COUNTDATABYSCENARIO_HOME_PAGE_KEY, isfdScenarioDataVo);
        }
        return isfdScenarioDataVo;
    }

    @Override
    public IsfdDataSourceDistributionVo getDataSourceDistribution(IsfdStatisticalAnalysisBo statisticalAnalysisBo,String source) {
        //先获取缓存，如果获取缓存失败再去db查，后期需要加锁
        Object cacheObject = RedisUtils.getCacheObject(RedisConstants.DISTRIBUTION_HOME_PAGE_KEY);
        if (cacheObject != null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            return (IsfdDataSourceDistributionVo) cacheObject;
        }
        List<IsfdDatabaseDataImportRecord> records = new ArrayList<>();
        IsfdDataSourceDistributionVo isfdDataSourceDistributionVo = new IsfdDataSourceDistributionVo();
        List<IsfdDataSourceDistributionVo.DataSourceDistribution> dataSourceList = new ArrayList<>();
        // 根据业务场景查询
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
            //查询要素库
            records = isfdStatisticalAnalysisMapper.getRecordsScenarioId(statisticalAnalysisBo.getScenarioId(),statisticalAnalysisBo.getSystemId(),"");
        }else{
            //查询所有场景的要素库
            records = isfdStatisticalAnalysisMapper.getRecordsScenarioId(null,null,"");
        }
        if(records.size()>0){
            //根据数据来源分组
            Map<String, List<IsfdDatabaseDataImportRecord>> groupedDataSource = records.stream()
                .collect(Collectors.groupingBy(IsfdDatabaseDataImportRecord::getImportMethod));
            final Long[] totalCount = {0L};
            //循环records
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            try{
                Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                for (IsfdDatabaseDataImportRecord isfdDatabaseDataImportRecord : records) {
                    semaphore.acquire(); // 获取许可，控制并发批次数
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        try {
                            //查询记录子表数据
                            List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(isfdDatabaseDataImportRecord.getId());
                            if (subList.size() > 0) {
                                for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                    //计算模型的数据量
                                    totalCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                }
                            } else {
                                //如果没有子表数据，则直接使用记录表数据量
                                totalCount[0] += isfdDatabaseDataImportRecord.getDataQuantity();
                            }
                        } catch (Exception e) {
                            log.error("record子记录表查询失败: {}", e.getMessage());
                        } finally {
                            semaphore.release(); // 释放资源
                        }
                    }, threadPoolTaskExecutor);
                    futures.add(future);
                }
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            }catch (Exception e) {
                log.error("统计失败 ：" + e.getMessage(), e);
            }
            //遍历groupedDataBase
            for (Map.Entry<String, List<IsfdDatabaseDataImportRecord>> entry : groupedDataSource.entrySet()) {
                String dataSource = entry.getKey();
                List<IsfdDatabaseDataImportRecord> tempDataBases = entry.getValue();
                //循环tempDataBases
                final Long[] dataCount = {0L};
                List<CompletableFuture<Void>> futures1 = new ArrayList<>();
                try{
                    Semaphore semaphore1 = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                    for (IsfdDatabaseDataImportRecord isfdDatabaseDataImportRecord : tempDataBases) {
                        semaphore1.acquire(); // 获取许可，控制并发批次数
                        CompletableFuture<Void> futures2 = CompletableFuture.runAsync(() -> {
                            try {
                                //查询记录子表数据
                                List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(isfdDatabaseDataImportRecord.getId());
                                if (subList.size() > 0) {
                                    for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                        //计算模型的数据量
                                        dataCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                    }
                                } else {
                                    //如果没有子表数据，则直接使用记录表数据量
                                    dataCount[0] += isfdDatabaseDataImportRecord.getDataQuantity();
                                }
                            } catch (Exception e) {
                                log.error("record子记录表查询失败: {}", e.getMessage());
                            } finally {
                                semaphore1.release(); // 释放资源
                            }
                        }, threadPoolTaskExecutor);
                        futures1.add(futures2);
                    }
                    CompletableFuture.allOf(futures1.toArray(new CompletableFuture[0])).join();
                }catch (Exception e) {
                    log.error("统计失败 ：" + e.getMessage(), e);
                }
                IsfdDataSourceDistributionVo.DataSourceDistribution dataSourceDistribution = new IsfdDataSourceDistributionVo.DataSourceDistribution();
                dataSourceDistribution.setDistribution(dataSource);
                dataSourceDistribution.setDataCount(dataCount[0]);
                //计算数据量占比
                if(totalCount[0] >0) {
                    BigDecimal bdDividend = new BigDecimal(dataCount[0] *100);
                    BigDecimal bdDivisor = new BigDecimal(totalCount[0]);

                    // Step2: 除法运算，保留两位小数，四舍五入
                    BigDecimal result = bdDividend.divide(bdDivisor, 2, RoundingMode.HALF_UP);
                    dataSourceDistribution.setDataCountRatio(result);
                }else{
                    dataSourceDistribution.setDataCountRatio(BigDecimal.ZERO);
                }
                dataSourceList.add(dataSourceDistribution);
            }
        }
        isfdDataSourceDistributionVo.setDataSourceDistribution(dataSourceList);
        if (cacheObject == null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            // 放入缓存中，永久有效
            RedisUtils.setCacheObject(RedisConstants.DISTRIBUTION_HOME_PAGE_KEY, isfdDataSourceDistributionVo);
        }
        return isfdDataSourceDistributionVo;
    }

    @Override
    public IsfdDataServiceVo dataServiceCount(IsfdStatisticalAnalysisBo statisticalAnalysisBo,String source) {
        IsfdDataServiceVo isfdDataServiceVo = new IsfdDataServiceVo();
        List<IsfdDatabaseDataImportRecord> records = new ArrayList<>();
        //先获取缓存，如果获取缓存失败再去db查，后期需要加锁
        Object cacheObject = RedisUtils.getCacheObject(RedisConstants.DATASERVICE_HOME_PAGE_KEY);
        if (cacheObject != null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            return (IsfdDataServiceVo) cacheObject;
        }
        // 根据业务场景查询
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
            //查询要素库
            records = isfdStatisticalAnalysisMapper.getRecordsScenarioId(statisticalAnalysisBo.getScenarioId(),statisticalAnalysisBo.getSystemId(),"API导入");
        }else{
            //查询所有场景的要素库
            records = isfdStatisticalAnalysisMapper.getRecordsScenarioId(null,null,"API导入");
        }
        if(records.size()>0){
            //根据业务场景分组
            Map<Long, List<IsfdDatabaseDataImportRecord>> groupedDataSource = records.stream()
                .collect(Collectors.groupingBy(IsfdDatabaseDataImportRecord::getSceneId));
            // 选择业务场景未选择业务系统
            List<IsfdDatabaseDataImportRecord> commonModelList = records.stream()
                .filter(record -> Objects.isNull(record.getSystemId()))
                .collect(Collectors.toList());
            List<IsfdDatabaseDataImportRecord> systemModelList = records.stream()
                .filter(record -> Objects.nonNull(record.getSystemId()))
                .collect(Collectors.toList());
            if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
                groupedDataSource = systemModelList.stream()
                    .collect(Collectors.groupingBy(IsfdDatabaseDataImportRecord::getSystemId));
            }
            final Long[] totalCount = {0L};
            //循环records
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            try{
                Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                for (IsfdDatabaseDataImportRecord isfdDatabaseDataImportRecord : records) {
                    semaphore.acquire(); // 获取许可，控制并发批次数
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        try {
                            //查询记录子表数据
                            List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(isfdDatabaseDataImportRecord.getId());
                            if (subList.size() > 0) {
                                for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                    //计算模型的数据量
                                    totalCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                }
                            } else {
                                //如果没有子表数据，则直接使用记录表数据量
                                totalCount[0] += isfdDatabaseDataImportRecord.getDataQuantity();
                            }
                        } catch (Exception e) {
                            log.error("record子记录表查询失败: {}", e.getMessage());
                        } finally {
                            semaphore.release(); // 释放资源
                        }
                    }, threadPoolTaskExecutor);
                    futures.add(future);
                }
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            }catch (Exception e) {
                log.error("统计失败 ：" + e.getMessage(), e);
            }
            isfdDataServiceVo.setDataTotalCount(totalCount[0]);
            //遍历groupedDataBase
            List<IsfdDataServiceVo.SenarioData> senarioDataList = new ArrayList<>();
            for (Map.Entry<Long, List<IsfdDatabaseDataImportRecord>> entry : groupedDataSource.entrySet()) {
                Long scenarioId = entry.getKey();
                IsfdDataServiceVo.SenarioData senarioData = new IsfdDataServiceVo.SenarioData();
                List<IsfdDataServiceVo.DataBaseTypeData> dataBaseTypeList = new ArrayList<>();
                IsfdBusinessScenarios isfdBusinessScenarios = isfdBusinessScenariosMapper.selectById(scenarioId);
                senarioData.setSenarioName(isfdBusinessScenarios.getName());
                List<IsfdDatabaseDataImportRecord> tempDataBases = entry.getValue();
                //根据dataBaseType分组
                Map<Long, List<IsfdDatabaseDataImportRecord>> groupedDataBaseType = tempDataBases.stream()
                    .collect(Collectors.groupingBy(IsfdDatabaseDataImportRecord::getDatabaseTypeId));
                for (Map.Entry<Long, List<IsfdDatabaseDataImportRecord>> entry1 : groupedDataBaseType.entrySet()) {
                    Long dataBaseTypeId = entry1.getKey();
                    IsfdDataServiceVo.DataBaseTypeData dataBaseTypeData = new IsfdDataServiceVo.DataBaseTypeData();
                    List<IsfdDatabaseDataImportRecord> tempDataBases1 = entry1.getValue();
                    IsfdDatabaseTypeManagement isfdDatabaseType = isfdDatabaseTypeManagementMapper.selectById(dataBaseTypeId);
                    dataBaseTypeData.setDataBaseName(isfdDatabaseType.getDatabaseName());
                    final Long[] dataCount = {0L};
                    if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())){
                        List<IsfdDatabaseDataImportRecord> filterList  = commonModelList.stream()
                            .filter(isfdBusinessDatabaseRef -> isfdBusinessDatabaseRef.getDatabaseTypeId().equals(dataBaseTypeId))
                            .collect(Collectors.toList());
                        if(filterList.size()>0){
                            // 将filterList加入到tempDataBases1
                            tempDataBases1.addAll(filterList);
                        }
                    }
                    List<CompletableFuture<Void>> futures1 = new ArrayList<>();
                    try{
                        Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                        for (IsfdDatabaseDataImportRecord isfdDatabaseDataImportRecord : tempDataBases1) {
                            semaphore.acquire(); // 获取许可，控制并发批次数
                            CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                                try {
                                    //查询记录子表数据
                                    List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(isfdDatabaseDataImportRecord.getId());
                                    if (subList.size() > 0) {
                                        for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                            //计算模型的数据量
                                            dataCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                        }
                                    } else {
                                        //如果没有子表数据，则直接使用记录表数据量
                                        dataCount[0] += isfdDatabaseDataImportRecord.getDataQuantity();
                                    }
                                } catch (Exception e) {
                                    log.error("record子记录表查询失败: {}", e.getMessage());
                                } finally {
                                    semaphore.release(); // 释放资源
                                }
                            }, threadPoolTaskExecutor);
                            futures1.add(future1);
                        }
                        CompletableFuture.allOf(futures1.toArray(new CompletableFuture[0])).join();
                    }catch (Exception e) {
                        log.error("统计失败 ：" + e.getMessage(), e);
                    }
                    dataBaseTypeData.setDataCount(dataCount[0]);
                    dataBaseTypeList.add(dataBaseTypeData);
                }
                //根据要素库名称分组
                Map<String, List<IsfdDataServiceVo.DataBaseTypeData>> groupedDataBaseName = dataBaseTypeList.stream()
                    .collect(Collectors.groupingBy(IsfdDataServiceVo.DataBaseTypeData::getDataBaseName));
                //遍历groupedDataBaseName
                List<IsfdDataServiceVo.DataBaseTypeData> dataBaseTypeList1 = new ArrayList<>();
                for (Map.Entry<String, List<IsfdDataServiceVo.DataBaseTypeData>> entry1 : groupedDataBaseName.entrySet()) {
                    String dataBaseName = entry1.getKey();
                    List<IsfdDataServiceVo.DataBaseTypeData> tempDataBases1 = entry1.getValue();
                    IsfdDataServiceVo.DataBaseTypeData dataBaseTypeData = new IsfdDataServiceVo.DataBaseTypeData();
                    Long dataCount = 0L;
                    for (IsfdDataServiceVo.DataBaseTypeData isfdDatabaseType : tempDataBases1) {
                        dataCount += isfdDatabaseType.getDataCount();
                    }
                    dataBaseTypeData.setDataBaseName(dataBaseName);
                    dataBaseTypeData.setDataCount(dataCount);
                    dataBaseTypeList1.add(dataBaseTypeData);
                }
                senarioData.setDataBaseDatas(dataBaseTypeList1);
                senarioDataList.add(senarioData);
            }
            //根据要素库分组
            Map<Long, List<IsfdDatabaseDataImportRecord>> groupedBaseSource = records.stream()
                .collect(Collectors.groupingBy(IsfdDatabaseDataImportRecord::getDatabaseTypeId));
            //遍历groupedBaseSource
            List<IsfdDataServiceVo.DataBaseTypeData> dataBaseTypeList = new ArrayList<>();
            for (Map.Entry<Long, List<IsfdDatabaseDataImportRecord>> entry : groupedBaseSource.entrySet()) {
                Long dataBaseTypeId = entry.getKey();
                IsfdDataServiceVo.DataBaseTypeData dataBaseTypeData = new IsfdDataServiceVo.DataBaseTypeData();
                List<IsfdDatabaseDataImportRecord> tempDataBases = entry.getValue();
                IsfdDatabaseTypeManagement isfdDatabaseType = isfdDatabaseTypeManagementMapper.selectById(dataBaseTypeId);
                dataBaseTypeData.setDataBaseName(isfdDatabaseType.getDatabaseName());
                final Long[] dataCount = {0L};
                List<CompletableFuture<Void>> futures1 = new ArrayList<>();
                try{
                    Semaphore semaphore = new Semaphore(THREAD_POOL_SIZE * 2); // 限制最大并发插入的
                    for (IsfdDatabaseDataImportRecord isfdDatabaseDataImportRecord : tempDataBases) {
                        semaphore.acquire(); // 获取许可，控制并发批次数
                        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                            try {
                                //查询记录子表数据
                                List<IsfdDatabaseDataImportSubRecord> subList = isfdStatisticalAnalysisMapper.getSubRecords(isfdDatabaseDataImportRecord.getId());
                                if (subList.size() > 0) {
                                    for (IsfdDatabaseDataImportSubRecord subRecord : subList) {
                                        //计算模型的数据量
                                        dataCount[0] += (subRecord.getImportQuantity() - subRecord.getDeleteQuantity());
                                    }
                                } else {
                                    //如果没有子表数据，则直接使用记录表数据量
                                    dataCount[0] += isfdDatabaseDataImportRecord.getDataQuantity();
                                }
                            } catch (Exception e) {
                                log.error("record子记录表查询失败: {}", e.getMessage());
                            } finally {
                                semaphore.release(); // 释放资源
                            }
                        }, threadPoolTaskExecutor);
                        futures1.add(future1);
                    }
                    CompletableFuture.allOf(futures1.toArray(new CompletableFuture[0])).join();
                }catch (Exception e) {
                    log.error("统计失败 ：" + e.getMessage(), e);
                }
                dataBaseTypeData.setDataCount(dataCount[0]);
                dataBaseTypeList.add(dataBaseTypeData);
            }
            //根据要素库名称分组
            Map<String, List<IsfdDataServiceVo.DataBaseTypeData>> groupedDataBaseName = dataBaseTypeList.stream()
                .collect(Collectors.groupingBy(IsfdDataServiceVo.DataBaseTypeData::getDataBaseName));
            //遍历groupedDataBaseName
            List<IsfdDataServiceVo.DataBaseTypeData> dataBaseTypeList1 = new ArrayList<>();
            for (Map.Entry<String, List<IsfdDataServiceVo.DataBaseTypeData>> entry1 : groupedDataBaseName.entrySet()) {
                String dataBaseName = entry1.getKey();
                List<IsfdDataServiceVo.DataBaseTypeData> tempDataBases1 = entry1.getValue();
                IsfdDataServiceVo.DataBaseTypeData dataBaseTypeData = new IsfdDataServiceVo.DataBaseTypeData();
                Long dataCount = 0L;
                for (IsfdDataServiceVo.DataBaseTypeData isfdDatabaseType : tempDataBases1) {
                    dataCount += isfdDatabaseType.getDataCount();
                }
                dataBaseTypeData.setDataBaseName(dataBaseName);
                dataBaseTypeData.setDataCount(dataCount);
                dataBaseTypeList1.add(dataBaseTypeData);
            }
            isfdDataServiceVo.setDataBaseTypeList(dataBaseTypeList1);
            isfdDataServiceVo.setSenarioDataList(senarioDataList);
        }
        if (cacheObject == null && source.equals("page") && Objects.isNull(statisticalAnalysisBo.getScenarioId())) {
            // 放入缓存中，永久有效
            RedisUtils.setCacheObject(RedisConstants.DATASERVICE_HOME_PAGE_KEY, isfdDataServiceVo);
        }
        return isfdDataServiceVo;
    }

    @Override
    public  byte[] pdfDownload(HttpServletResponse response,IsfdStatisticalAnalysisBo statisticalAnalysisBo) {
        // 查询业务场景名称
        String businessScenarioName = "";
        if(Objects.nonNull(statisticalAnalysisBo.getScenarioId())) {
            IsfdBusinessScenarios isfdBusinessScenarios = isfdBusinessScenariosMapper.selectById(statisticalAnalysisBo.getScenarioId());
            if (Objects.nonNull(isfdBusinessScenarios)) {
                businessScenarioName = isfdBusinessScenarios.getName();
            }
        }
        // 查询业务系统名称
        String businessSystemName = "";
        if(Objects.nonNull(statisticalAnalysisBo.getSystemId())) {
            IsfdBusinessScenarios isfdServerManagement = isfdBusinessScenariosMapper.selectById(statisticalAnalysisBo.getSystemId());
            if (Objects.nonNull(isfdServerManagement)) {
                businessSystemName = isfdServerManagement.getName();
            }
        }
        // 创建一个Word文档对象
        XWPFDocument document = new XWPFDocument();

        // 创建一个段落
        XWPFParagraph titleParagraph = document.createParagraph();
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("基础要素数据平台数据统计分析报表");
        titleRun.setFontSize(14);
        titleRun.setBold(true);
        // 设置居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        titleRun.addBreak(); // 添加换行
        XWPFParagraph bodyParagraph = document.createParagraph();
        XWPFRun bodyRun = bodyParagraph.createRun();
        bodyParagraph.setAlignment(ParagraphAlignment.LEFT);
        bodyRun.setText("业务场景：" + businessScenarioName);
        bodyRun.addBreak(); // 添加换行
        bodyRun.setText("业务系统：" + businessSystemName);
        bodyRun.addBreak(); // 添加换行
        bodyRun.setText("1、要素库数据资产统计");
        bodyRun.addBreak(); // 添加换行
        // 创建表格
        XWPFTable table = document.createTable();
        table.setWidth("100%");
        // 设置表格标题行
        XWPFTableRow headerRow = table.getRow(0);
        headerRow.getCell(0).setText("要素库名称");
        headerRow.addNewTableCell().setText("数据量");
        // 查询要素库数据资产统计
        IsfdDataAssetStatisticsVo isfdDataAssetStatisticsVo = this.dataAssetStatistics(statisticalAnalysisBo,"page");
        // 循环要素库数据资产统计
        if (isfdDataAssetStatisticsVo.getDataAssetList().size() > 0) {
            for (IsfdDataAssetStatisticsVo.DataAsset dataAsset : isfdDataAssetStatisticsVo.getDataAssetList()) {
                XWPFTableRow row = table.createRow();
                row.getCell(0).setText(dataAsset.getName());
                row.getCell(1).setText(String.valueOf(dataAsset.getCount()));
            }
        } else {
            XWPFTableRow row = table.createRow();
            row.getCell(0).setText("无数据");
            row.getCell(1).setText("0");
        }
        //设置表格宽度自适应页面
        for (XWPFTableRow row : table.getRows()) {
            for (XWPFTableCell cell : row.getTableCells()) {
                cell.setWidth("50%");
            }
        }
        //数据增长趋势
        XWPFParagraph bodyParagraph1 = document.createParagraph();
        XWPFRun bodyRun1 = bodyParagraph1.createRun();
        bodyParagraph1.setAlignment(ParagraphAlignment.LEFT);
        bodyRun1.addBreak(); // 添加换行
        bodyRun1.setText("2、要素库数据增长趋势");
        bodyRun1.addBreak(); // 添加换行
        // 查询要素库数据增长趋势
        IsfdGrowthTrendVo isfdGrowthTrendVo = this.growthTrend(statisticalAnalysisBo,"page");
        // 创建表格
        XWPFTable trendTable = document.createTable();
        trendTable.setWidth("100%");
        // 设置表格标题行
        XWPFTableRow trendHeaderRow = trendTable.getRow(0);
        trendHeaderRow.getCell(0).setText("");
        // 添加月份列
        for (IsfdGrowthTrendVo.ThrendData data : isfdGrowthTrendVo.getDataList()) {
            trendHeaderRow.addNewTableCell().setText(data.getName());
        }
        // 循环要素库数据增长趋势
        if (isfdGrowthTrendVo.getDataList().size() > 0) {
            // 添加月份行

            for (String month : isfdGrowthTrendVo.getMonthes()) {
                XWPFTableRow monthRow = trendTable.createRow();
                monthRow.getCell(0).setText(month);
                // 添加每个月的数据列
                for (IsfdGrowthTrendVo.ThrendData threndData : isfdGrowthTrendVo.getDataList()) {
                    // 获取当前循环下标
                    int index = isfdGrowthTrendVo.getDataList().indexOf(threndData) + 1; // +1 因为第0列是月份
                    // 查找对应月份的数据
                    IsfdGrowthTrendVo.MonthData monthData = threndData.getData().stream()
                        .filter(data -> data.getMonth().equals(month))
                        .findFirst()
                        .orElse(new IsfdGrowthTrendVo.MonthData(month, 0L));
                    monthRow.getCell(index).setText(String.valueOf(monthData.getDataCount()));
                }
            }
        } else {
            XWPFTableRow row = trendTable.createRow();
            row.getCell(0).setText("无数据");
            for (String month : isfdGrowthTrendVo.getMonthes()) {
                row.addNewTableCell().setText("0");
            }
        }
        //设置表格宽度自适应页面
        for (XWPFTableRow row : trendTable.getRows()) {
            Integer cellCount = row.getTableCells().size();
            // 根据单元格数量平均设置每个单元格的宽度
            for (int i = 0; i < cellCount; i++) {
                XWPFTableCell cell = row.getCell(i);
                cell.setWidth(String.valueOf(100 / cellCount) + "%");
            }
        }
        //要素库数据量统计
        XWPFParagraph bodyParagraph2 = document.createParagraph();
        XWPFRun bodyRun2 = bodyParagraph2.createRun();
        bodyParagraph2.setAlignment(ParagraphAlignment.LEFT);
        bodyRun2.addBreak(); // 添加换行
        bodyRun2.setText("3、要素库数据量统计");
        bodyRun2.addBreak(); // 添加换行
        // 业务场景/业务系统名称
        IsfdScenarioDataVo isfdScenarioDataVo =  this.countDataByScenario(statisticalAnalysisBo,"page");
        // 循环业务场景/业务系统名称
        if (isfdScenarioDataVo.getDataList().size() > 0) {
            //循环业务场景数据
            for (IsfdScenarioDataVo.ScenarioData scenarioData : isfdScenarioDataVo.getDataList()) {
                // 循环要素库数据
                XWPFParagraph bodyParagraphx = document.createParagraph();
                XWPFRun bodyRunx = bodyParagraphx.createRun();
                bodyParagraphx.setAlignment(ParagraphAlignment.LEFT);
                bodyRunx.setText("业务场景/业务系统：" + scenarioData.getScenarioName());
                // 创建表格scenarioTable+index
                XWPFTable scenarioTable = document.createTable();
                scenarioTable.setWidth("100%");
                // 设置表格标题行
                XWPFTableRow scenarioHeaderRow = scenarioTable.getRow(0);
                scenarioHeaderRow.getCell(0).setText("要素库名称");
                scenarioHeaderRow.addNewTableCell().setText("数据量");
                for (IsfdScenarioDataVo.DataBaseData dataBaseData : scenarioData.getDataBaseDatas()) {
                    XWPFTableRow row = scenarioTable.createRow();
                    row.getCell(0).setText(dataBaseData.getDataBaseName());
                    row.getCell(1).setText(String.valueOf(dataBaseData.getDataCount()));
                }
                bodyRunx.addBreak(); // 添加换行
            }
        }
        //数据来源统计
        XWPFParagraph bodyParagraph3 = document.createParagraph();
        XWPFRun bodyRun3 = bodyParagraph3.createRun();
        bodyParagraph3.setAlignment(ParagraphAlignment.LEFT);
        bodyRun3.addBreak(); // 添加换行
        bodyRun3.setText("4、数据来源统计");
        bodyRun3.addBreak(); // 添加换行
        // 查询数据来源统计
        IsfdDataSourceDistributionVo isfdDataSourceDistributionVo = this.getDataSourceDistribution(statisticalAnalysisBo,"page");
        // 创建表格
        XWPFTable dataSourceTable = document.createTable();
        dataSourceTable.setWidth("100%");
        // 设置表格标题行
        XWPFTableRow dataSourceHeaderRow = dataSourceTable.getRow(0);
        dataSourceHeaderRow.getCell(0).setText("数据来源");
        dataSourceHeaderRow.addNewTableCell().setText("数据量");
        dataSourceHeaderRow.addNewTableCell().setText("数据量占比");
        // 循环数据来源统计
        if (isfdDataSourceDistributionVo.getDataSourceDistribution().size() > 0) {
            for (IsfdDataSourceDistributionVo.DataSourceDistribution dataSourceDistribution : isfdDataSourceDistributionVo.getDataSourceDistribution()) {
                XWPFTableRow row = dataSourceTable.createRow();
                row.getCell(0).setText(dataSourceDistribution.getDistribution());
                row.getCell(1).setText(String.valueOf(dataSourceDistribution.getDataCount()));
                row.getCell(2).setText(dataSourceDistribution.getDataCountRatio().toString() + "%");
            }
        } else {
            XWPFTableRow row = dataSourceTable.createRow();
            row.getCell(0).setText("无数据");
            row.getCell(1).setText("0");
            row.getCell(2).setText("0%");
        }
        //数据服务统计
        XWPFParagraph bodyParagraph4 = document.createParagraph();
        XWPFRun bodyRun4 = bodyParagraph4.createRun();
        bodyParagraph4.setAlignment(ParagraphAlignment.LEFT);
        bodyRun4.addBreak(); // 添加换行
        bodyRun4.setText("5、数据服务统计");
        bodyRun4.addBreak(); // 添加换行
        // 查询数据服务统计
        IsfdDataServiceVo isfdDataServiceVo = this.dataServiceCount(statisticalAnalysisBo,"page");
        bodyRun4.setText("累计调用数据总量:"+ isfdDataServiceVo.getDataTotalCount() + "条");
        if (isfdDataServiceVo.getSenarioDataList().size() > 0) {
            //循环业务场景数据
            for (IsfdDataServiceVo.SenarioData scenarioData : isfdDataServiceVo.getSenarioDataList()) {
                // 循环要素库数据
                XWPFParagraph bodyParagraphx = document.createParagraph();
                XWPFRun bodyRunx = bodyParagraphx.createRun();
                bodyParagraphx.setAlignment(ParagraphAlignment.LEFT);
                bodyRunx.setText("业务场景/业务系统：" + scenarioData.getSenarioName());
                // 创建表格scenarioTable+index
                XWPFTable scenarioTable = document.createTable();
                scenarioTable.setWidth("100%");
                // 设置表格标题行
                XWPFTableRow scenarioHeaderRow = scenarioTable.getRow(0);
                scenarioHeaderRow.getCell(0).setText("要素库名称");
                scenarioHeaderRow.addNewTableCell().setText("数据量");
                for (IsfdDataServiceVo.DataBaseTypeData dataBaseData : scenarioData.getDataBaseDatas()) {
                    XWPFTableRow row = scenarioTable.createRow();
                    row.getCell(0).setText(dataBaseData.getDataBaseName());
                    row.getCell(1).setText(String.valueOf(dataBaseData.getDataCount()));
                }
                bodyRunx.addBreak(); // 添加换行
            }
        }
        // 创建一个字节数组输出流来保存文档
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            document.write(out); // 将文档写入字节数组输出流
            out.close(); // 关闭流
            document.close(); // 关闭文档对象
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 返回字节数组输出流中的数据作为二进制流
        return out.toByteArray();
    }

    @Override
    public Boolean cachedata(IsfdStatisticalAnalysisBo statisticalAnalysisBo) {
        IsfdDataAssetStatisticsVo IsfdDataAssetStatisticsVo = this.dataAssetStatistics(statisticalAnalysisBo,"cache");
        RedisUtils.setCacheObject(RedisConstants.DATAASSETSTATISTICS_HOME_PAGE_KEY, IsfdDataAssetStatisticsVo);
        IsfdGrowthTrendVo isfdGrowthTrendVo = this.growthTrend(statisticalAnalysisBo,"cache");
        RedisUtils.setCacheObject(RedisConstants.GROWTHTREND_HOME_PAGE_KEY, isfdGrowthTrendVo);
        IsfdScenarioDataVo isfdScenarioDataVo = this.countDataByScenario(statisticalAnalysisBo,"cache");
        RedisUtils.setCacheObject(RedisConstants.COUNTDATABYSCENARIO_HOME_PAGE_KEY, isfdScenarioDataVo);
        IsfdDataSourceDistributionVo isfdDataSourceDistributionVo = this.getDataSourceDistribution(statisticalAnalysisBo,"cache");
        RedisUtils.setCacheObject(RedisConstants.DISTRIBUTION_HOME_PAGE_KEY, isfdDataSourceDistributionVo);
        IsfdDataServiceVo isfdDataServiceVo = this.dataServiceCount(statisticalAnalysisBo,"cache");
        RedisUtils.setCacheObject(RedisConstants.DATASERVICE_HOME_PAGE_KEY, isfdDataServiceVo);

        // 九韶next平台的库数量的刷新
        isfdNextPlatformService.refreshCache("材料库");
        isfdNextPlatformService.refreshCache("紧固件库");
        isfdNextPlatformService.refreshCache("算法库");
        isfdNextPlatformService.refreshCache("参数库");
        isfdNextPlatformService.refreshCache("型材库");
        return true;
    }

    public static List<String> getMonthsBetween(String startStr, String endStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        if(StringUtils.isBlank(startStr)){
            endStr = LocalDate.now().format(formatter);
            // 开始时间向前推12个月
            startStr = LocalDate.now().minusMonths(12).format(formatter);
        }
        LocalDate startDate = LocalDate.parse(startStr, formatter);
        LocalDate endDate = LocalDate.parse(endStr, formatter);

        List<String> months = new ArrayList<>();
        LocalDate current = startDate.withDayOfMonth(1);  // 统一从每月1号开始
        while (!current.isAfter(endDate)) {
            months.add(current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            current = current.plusMonths(1);
        }
        // 处理结束月份超出范围的情况
        if (current.minusMonths(1).isAfter(endDate)) {
            months.remove(months.size() - 1);
        }
        return months;
    }
}
